﻿using SSRSURLBuilder.ReportService2005;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SSRSURLBuilder
{
    public partial class FormMain : Form
    {
        public ReportingService2005 RSService;
        string ReportPath = @"/";
        static char pathSeparator = '/';
        static char[] pathSeparatorArray = { pathSeparator };
        static string pathSeparatorString = new string(pathSeparator, 1);
        DataTable dtParam;

        public FormMain()
        {
            InitializeComponent();
            dtParam = new DataTable();
            dtParam.Columns.Add("Include", typeof(bool));
            dtParam.Columns.Add("ParameterName", typeof(string));
            dtParam.Columns.Add("DataType", typeof(string));
            dtParam.Columns.Add("Nullable", typeof(bool));
            dtParam.Columns.Add("State", typeof(string));
            dtParam.Columns.Add("MultiValue", typeof(bool));
            dtParam.Columns.Add("AllowBlank", typeof(bool));
            dtParam.Columns.Add("DefaultValuesQueryBased", typeof(bool));
            dtParam.Columns.Add("DefaultValues", typeof(string));
            dtParam.Columns.Add("QueryParameter", typeof(bool));
            dtParam.Columns.Add("ValidValuesQueryBased", typeof(bool));
            dtParam.Columns.Add("ValidValues", typeof(string));
            dtParam.Columns.Add("PromptUser", typeof(bool));
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            if (RSService != null)
            {
                if (MessageBox.Show("Changing Connection will reset everything. Are you sure?", "Confirm", MessageBoxButtons.YesNo) != DialogResult.Yes)
                {
                    return;
                }
            }

            Connection fc = new Connection();
            if (fc.ShowDialog() == DialogResult.OK)
            {
                lblServerInfo.Text = fc.RSService.Url.Replace("ReportService2005.asmx?wsdl", "");
                RSService = fc.RSService;
                CatalogItem[] catalogItems;
                catalogItems = RSService.ListChildren(ReportPath, true);
                BuildTree(catalogItems);
            }
        }

        private void BuildTree(CatalogItem[] catalogItems)
        {
            foreach (CatalogItem item in catalogItems)
            {
                if (item.Type == ItemTypeEnum.Report)
                {
                    string path = item.Path.Remove(0, ReportPath.Length);
                    string[] tokens = path.Split(pathSeparatorArray);
                    BuildNodesFromTokens(tokens, 0, trvFolders.Nodes);
                }
            }
        }

        private void BuildNodesFromTokens(string[] tokens, int index, TreeNodeCollection nodes)
        {
            TreeNode node = null;

            // first, see if a node for the current token exists on this level
            for (int i = 0; i < nodes.Count; i++)
            {
                if (nodes[i].Text == tokens[index])
                {
                    // a node was found at this level, no need to continue searching
                    node = nodes[i];
                    break;
                }
            }

            // no node was found, will need to create a new tree node
            if (node == null)
            {
                node = new TreeNode();
                node.Text = tokens[index];
                nodes.Add(node);

                // check if this is the final token, which means this token represents a report name
                if (tokens.Length - 1 == index)
                {
                    node.ImageIndex = 1;
                    node.SelectedImageIndex = 1;
                    node.Tag = String.Join(pathSeparatorString.ToString(), tokens);
                    // set the navigation property to 
                    // allow the user to click the report name
                    // and navigate to see the report
                    //node.NavigateUrl = "RenderReport.aspx?Path=" +
                    //   Server.UrlEncode(
                    //        String.Join(Global.PathSeparatorString.ToString(), tokens)
                    //   );
                }
                else
                {
                    node.ImageIndex = 0;
                    node.SelectedImageIndex = 0;
                }
            }

            // if we have not reached the end of the token list,
            // increase the level by (move down the tree) and 
            // call ourselves again
            index++;
            if (tokens.Length > index)
            {
                BuildNodesFromTokens(tokens, index, node.Nodes);
            }
        }

        private void trvFolders_DoubleClick(object sender, EventArgs e)
        {
            if (trvFolders.SelectedNode.Parent == null)
            {
                MessageBox.Show("Please Select a Report");
            }
            else
            {
                if (MessageBox.Show("Would you like to build URL Parameter for selected Report?", "Confirm", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    dtParam.Clear();
                    DataRow drParam;
                    lblReportPath.Text = @"/" + trvFolders.SelectedNode.Tag.ToString();

                    ReportParameter[] Parameter = RSService.GetReportParameters(@"/" + trvFolders.SelectedNode.Tag.ToString(), null, false, null, null);
                    for (int i = 0; i < Parameter.Length; i++)
                    {
                        drParam = dtParam.NewRow();
                        drParam[0] = false;
                        drParam[1] = Parameter[i].Name;
                        drParam[2] = Parameter[i].Type.ToString();
                        drParam[3] = Parameter[i].Nullable;
                        drParam[4] = Parameter[i].State;
                        drParam[5] = Parameter[i].MultiValue;
                        drParam[6] = Parameter[i].AllowBlank;
                        drParam[7] = Parameter[i].DefaultValuesQueryBased;
                        drParam[8] = Parameter[i].DefaultValues == null ? null : string.Join(";", Parameter[i].DefaultValues);
                        drParam[9] = Parameter[i].QueryParameter;
                        drParam[10] = Parameter[i].ValidValuesQueryBased;
                        drParam[11] = Parameter[i].ValidValues == null ? "" : string.Join(";", Parameter[i].ValidValues.Select(a => a.Value).ToArray());
                        drParam[12] = Parameter[i].PromptUser;
                        dtParam.Rows.Add(drParam);
                    }
                    dgvParameters.DataSource = dtParam;

                    for (int i = 1; i < dtParam.Columns.Count; i++)
                    {
                        dtParam.Columns[i].ReadOnly = true;
                    }
                }
                else
                {
                    return;
                }
            }
        }

        private void btnBuildURL_Click(object sender, EventArgs e)
        {
            if (lblReportPath.Text.Contains("<"))
            {
                MessageBox.Show("Select a Report First");
                return;
            }

            string ReportServer = RSService.Url.Replace("/ReportService2005.asmx?wsdl", "") + "?";
            string URL = ReportServer + lblReportPath.Text;

            //Get Selected Parameters
            foreach (DataRow dr in dtParam.Select("Include=1", "ParameterName"))
            {
                if (Convert.ToBoolean(dr["PromptUser"].ToString()))
                {
                    URL += "&" + dr["ParameterName"].ToString() + "=" + GetSampleParameterValue(dr["DataType"].ToString());
                    if (Convert.ToBoolean(dr["MultiValue"].ToString()))
                    {
                        URL += "&" + dr["ParameterName"].ToString() + "=" + GetSampleParameterValue(dr["DataType"].ToString());
                    }
                }
            }

            //Handle Rendering
            if (cmbRenderExtension.SelectedIndex != -1)
            {
                URL += "&rs:Format=" + cmbRenderExtension.SelectedItem.ToString();
            }

            //Handle Toolbar & Parameters Area
            if (!cbxToolbar.Checked)
            {
                URL += "&rc:Toolbar=false";
            }

            if (!cbxToolbar.Checked)
            {
                URL += "&rc:Parameters=false";
            }

            rtbURL.Text = "";
            rtbURL.AppendText(URL);
        }
        private string GetSampleParameterValue(string DataType)
        {
            //There are only 5 types of parameter allowed in SSRS
            switch (DataType)
            {
                case "String":
                    return "SAMPLE";
                case "Boolean":
                    return "0";
                case "DateTime":
                    return DateTime.Now.ToString("yyyy-MM-dd");
                case "Integer":
                    return "999";
                case "Float":
                    return "17.5";
                default:
                    return "#NA";
            }
        }

        private void btnCopy_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(rtbURL.Text))
            {
                Clipboard.SetText(rtbURL.Text);
            }
            
        }
    }
}
